#!/usr/bin/env bash

# 脚本功能：自动构建并安装项目（支持自定义OpenSSL与工具链路径）
# 用法（新版本格式）：
#   1) 构建并安装：
#      ./cmake-build.sh -p <安装路径> [--openssl-root <OPENSSL_ROOT_DIR>] [--toolchain <CMAKE_TOOLCHAIN_FILE>]
#      也支持等号形式：-p=/path --openssl-root=/path --toolchain=/path
#   2) 仅清理：
#      ./cmake-build.sh -c
#   3) 先清理再构建：
#      ./cmake-build.sh -c -p <安装路径> [可选参数同上]
# 用法（旧版本格式，兼容支持）：
#   1) 构建并安装：
#      ./cmake-build.sh <安装路径>
#   2) 仅清理：
#      ./cmake-build.sh clean
#   3) 先清理再构建：
#      ./cmake-build.sh clean <安装路径>
# 示例：
#   新版本: ./cmake-build.sh -p /home/user/install_dir --openssl-root /opt/openssl-1.1 --toolchain /opt/tc/toolchain.cmake
#   旧版本: ./cmake-build.sh clean install

set -e  # 遇到错误立即退出

# 获取当前脚本运行路径
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "当前脚本路径: $SCRIPT_DIR"

# 判断当前是否在build目录下
if [[ "$SCRIPT_DIR" == */build ]]; then
    # 在build目录下，root路径为../
    ROOT_PATH="$(dirname "$SCRIPT_DIR")"
    echo "检测到在build目录下，root路径: $ROOT_PATH"
else
    # 在根目录下，root路径为当前路径
    ROOT_PATH="$SCRIPT_DIR"
    echo "检测到在根目录下，root路径: $ROOT_PATH"
fi

# 检查root路径下是否存在CMakeLists.txt
if [[ ! -f "$ROOT_PATH/build/CMakeLists.txt" ]]; then
    echo "错误: 在root路径 $ROOT_PATH 下未找到CMakeLists.txt文件"
    exit 1
fi

# 创建CMakeLists.txt软连接到当前目录
if [[ -L "$ROOT_PATH/CMakeLists.txt" ]]; then
    echo "删除已存在的CMakeLists.txt软连接"
    rm "$ROOT_PATH/CMakeLists.txt"
fi

echo "创建CMakeLists.txt软连接到: $ROOT_PATH/build/CMakeLists.txt"
ln -s "$ROOT_PATH/build/CMakeLists.txt" "$ROOT_PATH/CMakeLists.txt"

# 默认路径（可被环境变量或CLI参数覆盖）
DEFAULT_OPENSSL_ROOT_DIR=""
DEFAULT_CMAKE_TOOLCHAIN_FILE=""

# CLI覆盖变量（优先级最高）
CLI_OPENSSL_ROOT_DIR=""
CLI_CMAKE_TOOLCHAIN_FILE=""

INSTALL_PATH=""
CLEAN=0
SHOW_HELP=0

print_help() {
  echo "--------------------------------"
  echo "  VBS 构建需要 OpenSSL 1.1"
  echo "  请先安装 OpenSSL 1.1"
  echo "  安装方法："
  echo "  sudo apt-get update"
  echo "  sudo apt-get install libssl-dev"
  echo "  sudo apt-get install libssl1.1"
  echo "--------------------------------"
  echo "用法（新版本格式）:"
  echo "  $0 -p <安装路径> [--openssl-root <OPENSSL_ROOT_DIR>] [--toolchain <CMAKE_TOOLCHAIN_FILE>]"
  echo "  $0 -p=/path [--openssl-root=/path] [--toolchain=/path]"
  echo "  $0 -c"
  echo "  $0 -c -p <安装路径> [--openssl-root ...] [--toolchain ...]"
  echo ""
  echo "用法（旧版本格式，兼容支持）:"
  echo "  $0 <安装路径>"
  echo "  $0 clean"
  echo "  $0 clean <安装路径>"
  echo ""
  echo "示例:"
  echo "  新版本: $0 -p /home/user/install_dir --openssl-root /opt/openssl-1.1 --toolchain /opt/tc/toolchain.cmake"
  echo "  旧版本: $0 clean install"
}

# 解析参数（支持新版本 --key value 与旧版本 clean install 两种形式）
while [[ $# -gt 0 ]]; do
  case "$1" in
    -h|--help)
      SHOW_HELP=1
      shift
      ;;
    -c|--clean)
      CLEAN=1
      shift
      ;;
    clean)
      # 兼容旧版本：clean 命令
      CLEAN=1
      shift
      ;;
    -p)
      if [[ -n "${2:-}" ]]; then
        INSTALL_PATH="$2"
        shift 2
      else
        echo "错误: -p 需要一个安装路径参数"
        exit 1
      fi
      ;;
    -p=*)
      INSTALL_PATH="${1#*=}"
      shift
      ;;
    --path)
      if [[ -n "${2:-}" ]]; then
        INSTALL_PATH="$2"
        shift 2
      else
        echo "错误: --path 需要一个安装路径参数"
        exit 1
      fi
      ;;
    --path=*)
      INSTALL_PATH="${1#*=}"
      shift
      ;;
    --openssl-root)
      if [[ -n "${2:-}" ]]; then
        CLI_OPENSSL_ROOT_DIR="$2"
        shift 2
      else
        echo "错误: --openssl-root 需要一个路径参数"
        exit 1
      fi
      ;;
    --openssl-root=*)
      CLI_OPENSSL_ROOT_DIR="${1#*=}"
      shift
      ;;
    --toolchain)
      if [[ -n "${2:-}" ]]; then
        CLI_CMAKE_TOOLCHAIN_FILE="$2"
        shift 2
      else
        echo "错误: --toolchain 需要一个路径参数"
        exit 1
      fi
      ;;
    --toolchain=*)
      CLI_CMAKE_TOOLCHAIN_FILE="${1#*=}"
      shift
      ;;
    *)
      # 兼容旧版本：如果第一个参数不是已知的选项，且没有设置安装路径，则将其作为安装路径
      if [[ -z "$INSTALL_PATH" && "$1" != clean ]]; then
        INSTALL_PATH="$1"
        shift
      else
        echo "未知参数: $1"
        echo "使用 $0 --help 查看帮助信息"
        exit 1
      fi
      ;;
  esac
done

if [[ $SHOW_HELP -eq 1 ]]; then
  print_help
  exit 0
fi

# 仅清理
if [[ $CLEAN -eq 1 && -z "$INSTALL_PATH" ]]; then
  echo "正在清空构建目录 $ROOT_PATH/out/vbs ..."
  rm -rf "$ROOT_PATH/out/vbs"
  echo "清空完成。"
  exit 0
fi

# 先清理再构建
if [[ $CLEAN -eq 1 && -n "$INSTALL_PATH" ]]; then
  echo "正在清空构建目录 $ROOT_PATH/out/vbs ..."
  rm -rf "$ROOT_PATH/out/vbs"
  echo "清空完成，开始构建..."
fi

# 无安装路径则打印帮助
if [[ -z "$INSTALL_PATH" ]]; then
  print_help
  exit 0
fi

# 确定最终 OPENSSL_ROOT_DIR 与 CMAKE_TOOLCHAIN_FILE（优先级：CLI > 环境变量 > 默认）
if [[ -n "$CLI_OPENSSL_ROOT_DIR" ]]; then
  OPENSSL_ROOT_DIR="$CLI_OPENSSL_ROOT_DIR"
fi
OPENSSL_ROOT_DIR="${OPENSSL_ROOT_DIR:-$DEFAULT_OPENSSL_ROOT_DIR}"

if [[ -n "$CLI_CMAKE_TOOLCHAIN_FILE" ]]; then
  CMAKE_TOOLCHAIN_FILE="$CLI_CMAKE_TOOLCHAIN_FILE"
fi
CMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE:-$DEFAULT_CMAKE_TOOLCHAIN_FILE}"

# 判定是否使用工具链（仅当路径存在才视为配置了工具链）
USE_TOOLCHAIN=0
if [[ -n "$CMAKE_TOOLCHAIN_FILE" ]] && [[ -f "$CMAKE_TOOLCHAIN_FILE" ]]; then
  USE_TOOLCHAIN=1
fi

# 交叉编译时必须指定OpenSSL路径
if [[ $USE_TOOLCHAIN -eq 1 ]] && [[ -z "$CLI_OPENSSL_ROOT_DIR" ]]; then
  echo "错误: 使用交叉编译时必须指定 --openssl-root 参数"
  echo "请使用: $0 -p <安装路径> --toolchain <工具链文件> --openssl-root <OpenSSL路径>"
  exit 1
fi

# 设置OpenSSL相关子路径
OPENSSL_INCLUDE_DIR="${OPENSSL_ROOT_DIR}/include"
OPENSSL_LIBRARIES="${OPENSSL_ROOT_DIR}/lib"
OPENSSL_CRYPTO_LIBRARY="${OPENSSL_ROOT_DIR}/lib/libcrypto.so"
OPENSSL_SSL_LIBRARY="${OPENSSL_ROOT_DIR}/lib/libssl.so"

# 仅在交叉编译（使用工具链）时验证OpenSSL路径
if [[ $USE_TOOLCHAIN -eq 1 ]]; then
  if [ ! -f "$OPENSSL_CRYPTO_LIBRARY" ] || [ ! -f "$OPENSSL_SSL_LIBRARY" ]; then
    echo "错误: OpenSSL库文件不存在！"
    echo "请确保OpenSSL已正确构建在: $OPENSSL_ROOT_DIR"
    echo "或者运行: ./build_openssl_arm64.sh 来构建OpenSSL"
    exit 1
  fi
fi

# 显示配置
echo "使用安装路径: $INSTALL_PATH"
if [[ $USE_TOOLCHAIN -eq 1 ]]; then
  echo "使用工具链文件: $CMAKE_TOOLCHAIN_FILE"
else
  echo "未配置可用的工具链文件，采用本机构建（不传递工具链）。"
fi

if [[ $USE_TOOLCHAIN -eq 1 ]]; then
  echo "使用OpenSSL路径: $OPENSSL_ROOT_DIR"
  echo "使用OpenSSL_INCLUDE_DIR路径: $OPENSSL_INCLUDE_DIR"
  echo "使用OpenSSL_LIBRARIES路径: $OPENSSL_LIBRARIES"
  echo "使用OpenSSL_CRYPTO_LIBRARY路径: $OPENSSL_CRYPTO_LIBRARY"
  echo "使用OpenSSL_SSL_LIBRARY路径: $OPENSSL_SSL_LIBRARY"
else
  echo "未指定外部OpenSSL路径，将由CMake在本机环境中查找OpenSSL。"
fi

# 1. 创建构建目录
mkdir -p "$ROOT_PATH/out/vbs"

# 2. 进入构建目录
cd "$ROOT_PATH/out/vbs"
mkdir -p "$INSTALL_PATH"

# 3. 配置CMake - 根据是否使用工具链分支
# 注意：环境变量设置可在工具链文件中处理
if [[ $USE_TOOLCHAIN -eq 1 ]]; then
  cmake -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN_FILE" \
    -DSECURITY=ON \
    -DVBSAUTH=ON \
    -DIS_THIRDPARTY_BOOST_OK=ON \
    -DIS_THIRDPARTY_BOOST_SUPPORTED=ON \
    -DCONAN_BUILD=OFF \
    -DCONAN_PLATFORM=j5 \
    -DBUILD_SHARED_LIBS=ON \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" \
    -DOPENSSL_ROOT_DIR="$OPENSSL_ROOT_DIR" \
    -DOPENSSL_INCLUDE_DIR="$OPENSSL_INCLUDE_DIR" \
    -DOPENSSL_LIBRARIES="$OPENSSL_LIBRARIES" \
    -DOPENSSL_CRYPTO_LIBRARY="$OPENSSL_CRYPTO_LIBRARY" \
    -DOPENSSL_SSL_LIBRARY="$OPENSSL_SSL_LIBRARY" \
    ../..
else
  cmake -G Ninja \
    -DSECURITY=ON \
    -DVBSAUTH=ON \
    -DIS_THIRDPARTY_BOOST_OK=ON \
    -DIS_THIRDPARTY_BOOST_SUPPORTED=ON \
    -DCONAN_BUILD=OFF \
    -DCONAN_PLATFORM=x64 \
    -DBUILD_SHARED_LIBS=ON \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" \
    ../..
fi

# 4. 构建项目
cmake --build .

# 5. 安装项目
cmake --install . --prefix "$INSTALL_PATH"

echo "构建和安装完成，安装路径：$INSTALL_PATH"
